interface Array<T> {
  forEachCustom(callback: (element: T, index?: number, array?: T[]) => void, thisArg?): void,
  filterCustom(callback: (element: T, index?: number, array?: T[]) => any, thisArg?): T[],
  mapCustom(callback: (element: T, index?: number, array?: T[]) => T, thisArg?): T[],
  findCustom(callback: (element: T, index?: number, array?: T[]) => any, thisArg?): T,
  pushCustom(...items: T[]): number,
  findIndexCustom(callback: (element: T, index?: number, array?: T[]) => any, thisArg?): -1 | number
}
// Polyfill

// forEach实现
Array.prototype.forEachCustom = function (callback, thisArg) {
  if (this == null) {
    throw new TypeError("this is null or not defined");
  }
  if (typeof callback !== "function") {
    throw new TypeError(callback + " is not a function");
  }
  var O = Object(this); //避免取length时报错

  var len = O.length;
  var T, I;
  if (arguments.length > 1) {
    T = thisArg;
  }
  for (I = 0; I < len; I++) {
    var IValue;
    if (I in O) {
      IValue = O[I];
      // this,currentItem,index,currentArray
      callback.call(T, IValue, I, O);
    }
  }
};
// filter实现
Array.prototype.filterCustom = function (callback, thisArg) {
  var T, K;
  if (this === null) {
    throw new TypeError(" this is null or not defined");
  }
  if (typeof callback !== "function") {
    throw new TypeError(callback + " is not a function");
  }
  if (arguments.length > 1) {
    T = thisArg;
  }
  var O = Object(this);
  var len = O.length;
  K = 0;
  var res = new Array();
  while (K < len) {
    do {
      if (!(K in this)) {
        break;
      }
      var KValue = O[K];
      if (callback.call(T, KValue, K, O)) {
        res[res.length] = KValue;
      }
    } while (false);
    K++;
  }
  return res;
};
// map实现
Array.prototype.mapCustom = function (callback, thisArg) {
  var T, K;
  if (this === null) {
    throw new TypeError(" this is null or not defined");
  }
  if (typeof callback !== "function") {
    throw new TypeError(callback + " is not a function");
  }
  if (arguments.length > 1) {
    T = thisArg;
  }
  K = 0;
  var O = Object(this);
  var len = O.length;
  var res = new Array(len);
  while (K < len) {
    var KValue;
    if (K in O) {
      KValue = callback.call(T, O[K], K, O);
    }
    res[K] = KValue;
    K++;
  }
  return res;
};
// find实现
Array.prototype.findCustom = function (callback, thisArg) {
  var T, K;
  if (this === null) {
    throw new TypeError(" this is null or not defined");
  }
  if (typeof callback !== "function") {
    throw new TypeError(callback + " is not a function");
  }
  if (arguments.length > 1) {
    T = thisArg;
  }
  K = 0;
  var O = Object(this);
  var len = O.length;
  while (K < len) {
    if (callback.call(T, O[K], K, O)) {
      return O[K];
    }
    K++;
  }
  return;
};
// push实现
Array.prototype.pushCustom = function () {
  if (this === null) {
    throw new TypeError("this is null or not defined");
  }
  var N = this.length;
  var len = arguments.length;
  var K = 0;
  while (K < len) {
    this[N + K] = arguments[K];
    K++;
  }
  return N + K;
};

// findIndex实现
Array.prototype.findIndexCustom = function (callback, thisArg) {
  if (this === null) {
    throw new TypeError("this is null or not defined");
  }
  if (typeof callback !== "function") {
    throw new TypeError(callback + " is not a function");
  }
  var T, K
  var O = Object(this)
  var len = O.length >>> 0
  K = 0
  if (arguments.length > 1) {
    T = thisArg
  }
  while (K < len) {
    if (callback.call(T, O[K], K, O)) {
      return K
    }
    K++
  }
  return -1
}



const arr = [1, 2, 3, 4];

const result = arr.forEachCustom(item => {
  // console.log(item);
}
);

console.log(arr.findIndexCustom(item => item === 2));


console.log(result, arr);
